#!/bin/bash
# 批量转换 png -> webp
# brew install webp
# ./png_to_webp.sh <source_directory> [quality] [delete_png]

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
BOLD='\033[1m'

# 检查基本命令是否可用
check_basic_commands() {
    local required_commands=("dirname" "basename" "find" "stat")
    local missing_commands=()
    
    for cmd in "${required_commands[@]}"; do
        if ! command -v "$cmd" >/dev/null 2>&1; then
            missing_commands+=("$cmd")
        fi
    done
    
    if [ ${#missing_commands[@]} -ne 0 ]; then
        echo -e "${RED}错误: 缺少必要的系统命令:${NC}"
        printf '  - %s\n' "${missing_commands[@]}"
        echo "请确保系统已正确安装这些基本命令。"
        exit 1
    fi
}

# 查找 cwebp 命令
find_cwebp() {
    # 检查系统 PATH 中是否有 cwebp
    if command -v cwebp &> /dev/null; then
        CWEBP_PATH=$(command -v cwebp)
        force_flush "${GREEN}✓ 使用系统 cwebp 命令: $CWEBP_PATH${NC}"
        return 0
    fi
    
    # 如果没有找到 cwebp，显示错误信息并退出
    force_flush "${RED}错误: 未找到 cwebp 命令。${NC}"
    echo "请按照以下步骤安装 WebP 工具："
    
    case "$(uname -s)" in
        "Darwin")
            echo "macOS:"
            echo "  brew install webp"
            ;;
        "Linux")
            echo "Ubuntu/Debian:"
            echo "  sudo apt-get update && sudo apt-get install webp"
            echo
            echo "CentOS/RHEL:"
            echo "  sudo yum install libwebp-tools"
            echo
            echo "Arch Linux:"
            echo "  sudo pacman -S libwebp"
            ;;
        "MINGW"*|"MSYS"*|"CYGWIN"*)
            echo "Windows:"
            echo "1. 使用 Chocolatey:"
            echo "   choco install webp"
            echo
            echo "2. 或从官方下载安装包:"
            echo "   https://developers.google.com/speed/webp/download"
            ;;
    esac
    
    echo
    echo "如果您无法安装 WebP 工具，请联系开发者获取支持。"
    exit 1
}

# 格式化文件大小函数
format_size() {
    local size=$1
    local units=("B" "KB" "MB" "GB")
    local unit=0
    
    # 使用 awk 来处理浮点数比较，避免 "integer expression expected" 错误
    while [ $(awk -v s="$size" 'BEGIN {print (s > 1024)}') -eq 1 ] && [ $unit -lt 3 ]; do
        size=$(echo "scale=2; $size/1024" | bc)
        ((unit++))
    done
    
    printf "%.2f %s" $size "${units[$unit]}"
}

# 比较浮点数函数
compare_float() {
    awk -v n1="$1" -v n2="$2" 'BEGIN {if (n1>=n2) exit 0; exit 1}'
}

# 强制刷新输出
force_flush() {
    echo -en "\r\033[K"  # 清除当前行
    echo -e "$1"
}

# 检查文件权限
check_file_permissions() {
    local file="$1"
    local dir=$(dirname "$file")
    
    # 检查源文件读取权限
    if [ ! -r "$file" ]; then
        force_flush "\n${RED}错误: 无法读取文件 $file${NC}"
        echo "请检查文件权限，确保当前用户有读取权限。"
        return 1
    fi
    
    # 检查目标目录写入权限
    if [ ! -w "$dir" ]; then
        force_flush "\n${RED}错误: 无法写入目录 $dir${NC}"
        echo "请检查目录权限，确保当前用户有写入权限。"
        return 1
    fi
    
    return 0
}

# 检查参数
if [ -z "$1" ]; then
    force_flush "${RED}错误: 缺少必要参数${NC}"
    echo "用法: $0 <source_directory> [quality] [delete_png]"
    echo "  source_directory: 源文件夹路径"
    echo "  quality: WebP 质量 (0-100), 默认 85"
    echo "  delete_png: 是否删除原始 PNG 文件 (0|1), 默认 0"
    exit 1
fi

# 检查基本命令
check_basic_commands

# 检查并设置 cwebp 路径
find_cwebp

# 源目录
SOURCE_DIR=$(cd "$(dirname "$1")" && pwd)/$(basename "$1")

# WebP 质量设置 (0-100)
QUALITY=${2:-85}

# 是否删除原始 PNG
DELETE_PNG=${3:-0}

if [ ! -d "$SOURCE_DIR" ]; then
    force_flush "${RED}错误: $SOURCE_DIR 不是一个有效的目录。${NC}"
    exit 1
fi

force_flush "\n${BOLD}🔧 转换配置:${NC}"
echo -e "${BLUE}📁 源目录:${NC} $SOURCE_DIR"
echo -e "${BLUE}⚙️  WebP 质量:${NC} $QUALITY"
echo -e "${BLUE}🗑️  删除原始 PNG:${NC} $([ "$DELETE_PNG" = "1" ] && echo "是" || echo "否")"

force_flush "\n${BOLD}🔍 开始扫描文件...${NC}"

# 计数器
TOTAL_FILES=$(find "$SOURCE_DIR" -type f -name "*.png" | wc -l | tr -d ' ')
CURRENT=0
CONVERTED=0
FAILED=0

if [ "$TOTAL_FILES" -eq 0 ]; then
    force_flush "${YELLOW}警告: 未找到任何 PNG 文件！${NC}"
    exit 0
fi

force_flush "${GREEN}找到 ${TOTAL_FILES} 个 PNG 文件待转换${NC}\n"

# 进度条函数
show_progress() {
    local current=$1
    local total=$2
    local width=50
    local percentage=$((current * 100 / total))
    local completed=$((width * current / total))
    local remaining=$((width - completed))
    
    printf "\r["
    printf "%${completed}s" | tr ' ' '='
    printf ">"
    printf "%${remaining}s" | tr ' ' ' '
    printf "] %3d%% (%d/%d)" "$percentage" "$current" "$total"
}

# 遍历目录中的所有 png 文件并转换
while IFS= read -r file; do
    # 更新计数
    ((CURRENT++))
    
    # 获取文件目录和文件名（不含扩展名）
    dir=$(dirname "$file")
    base=$(basename "$file" .png)
    
    # 检查文件权限
    if ! check_file_permissions "$file"; then
        ((FAILED++))
        continue
    fi
    
    # 获取原始文件大小
    original_size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
    original_size_formatted=$(format_size $original_size)
    
    # 显示进度条
    show_progress "$CURRENT" "$TOTAL_FILES"
    
    # 使用 cwebp 转换文件为 webp 格式
    conversion_output=$("$CWEBP_PATH" -quiet -q "$QUALITY" "$file" -o "$dir/$base.webp" 2>&1)
    if [ $? -eq 0 ] && [ -f "$dir/$base.webp" ]; then
        # 获取转换后文件大小
        webp_size=$(stat -f%z "$dir/$base.webp" 2>/dev/null || stat -c%s "$dir/$base.webp" 2>/dev/null)
        webp_size_formatted=$(format_size $webp_size)
        
        # 计算压缩比例
        compression_ratio=$(echo "scale=2; ($original_size - $webp_size) * 100 / $original_size" | bc)
        
        # 显示大小对比
        force_flush "\n${BLUE}📊 $file${NC}"
        echo -e "   PNG: ${YELLOW}$original_size_formatted${NC}"
        echo -e "   WebP: ${GREEN}$webp_size_formatted${NC}"
        echo -e "   压缩率: ${GREEN}${compression_ratio}%${NC}"
        
        ((CONVERTED++))
        
        # 如果设置了删除原始文件
        if [ "$DELETE_PNG" = "1" ]; then
            rm "$file"
        fi
    else
        ((FAILED++))
        force_flush "\n${RED}❌ 转换失败: $file${NC}"
        if [ -n "$conversion_output" ]; then
            echo -e "   ${YELLOW}原因: $conversion_output${NC}"
        fi
    fi
done < <(find "$SOURCE_DIR" -type f -name "*.png")

# 完成
force_flush "\n\n${BOLD}🎉 全部完成！${NC}"
echo -e "${GREEN}转换成功: ${CONVERTED} / ${TOTAL_FILES}${NC}"
if [ "$FAILED" -gt 0 ]; then
    echo -e "${RED}转换失败: ${FAILED}${NC}"
else
    echo -e "${GREEN}转换失败: 0${NC}"
fi

if [ "$DELETE_PNG" = "1" ]; then
    echo -e "${YELLOW}已删除原始 PNG 文件。${NC}"
fi

exit 0